package cn.trymore.core.util;

import java.util.ArrayList;
import java.util.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;

public class UtilDate {
	
	public UtilDate(){}
	
	private static String defaultDatePattern = "yyyy-MM-dd HH:mm:ss";
	private static SimpleDateFormat defaultFormatter = new SimpleDateFormat(defaultDatePattern);
	
	public static String getDatePattern(){
		return defaultDatePattern;
	}
	
	public static SimpleDateFormat getDefaultDateFormatter(){
		return defaultFormatter;
	}
	
	public static Timestamp getNowTime(){
		return new Timestamp(new java.util.Date().getTime());
	}
	
	public static String parseTime(Date date) {
		return new SimpleDateFormat(defaultDatePattern).format(date);
	}
	
	public static String parseTime(Date date, String pattern) {
		return new SimpleDateFormat(pattern).format(date);
	}
	
	public static String parseTime(Timestamp time){
		return getDefaultDateFormatter().format(new java.sql.Date(time.getTime()));
	}
	
	/** 
	  * 取得指定日期所在周的第一天 
	  */ 
	public static Date getFirstDayOfWeek(Date date) {
		Calendar c = new GregorianCalendar();
		c.setFirstDayOfWeek(Calendar.MONDAY);
		c.setTime(date); 
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek()); // Monday 
		return c.getTime (); 
	}
	
	/** 
	 * 取得指定日期所在周的最后一天 
	 */ 
	public static Date getLastDayOfWeek(Date date) { 
		Calendar c = new GregorianCalendar(); 
		c.setFirstDayOfWeek(Calendar.MONDAY); 
		c.setTime(date); 
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6); // Sunday 
		return c.getTime(); 
	}
	
	/** 
	 * 获取当前周数
	 */ 
	public static int getWeekNumber(){ 
		return getWeekNumber(new Date());
	}
	
	/** 
	 * 获取当前周数
	 * @param date
	 */ 
	public static int getWeekNumber(Date date){ 
		Calendar calendar = Calendar.getInstance();
		calendar.setFirstDayOfWeek(Calendar.MONDAY);
		calendar.setTime(date);
		return calendar.get(Calendar.WEEK_OF_YEAR);
	}
	
	/**
	 * 获取当年某周的第一天
	 * 
	 * @param week
	 * @return
	 */
	public static Date getFirstDayOfWeek(int week) {
		return getFirstDayOfWeek(getCurrentYear(), week);
	}
	
	/**
	 * 获取某年某周的第一天
	 * 
	 * @param year
	 * @param week
	 * @return
	 */
	public static Date getFirstDayOfWeek(int year, int week) {
		Calendar calendar = new GregorianCalendar();
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONDAY, Calendar.JANUARY);
		calendar.set(Calendar.DATE, 1);
		
		Calendar cal = (GregorianCalendar) calendar.clone();
		cal.add(Calendar.DATE, (week - 1) * 7);
		
		return getFirstDayOfWeek(cal.getTime());
	}
	
	/**
	 * 获取某一周从周一到周日的日期
	 * 
	 * @param week
	 * @return
	 */
	public static List<String> getWholeWeekDate (int week)
	{
		return getWholeWeekDate(getCurrentYear(), week);
	}
	
	/**
	 * 获取某一周从周一到周日的日期
	 * 
	 * @param year
	 * @param week
	 * @return
	 */
	public static List<String> getWholeWeekDate (int year, int week)
	{
		List<String> weekDates = new ArrayList<String>();
		Date monday = getFirstDayOfWeek(year, week);
		weekDates.add(UtilDate.parseTime(monday, "yyyy-MM-dd"));
		
		for (int i = 1; i < 7; i++)
		{
			Date date = new Date();
			date.setTime(monday.getTime() + (i * 24 * 3600000));
			weekDates.add(UtilDate.parseTime(date, "yyyy-MM-dd"));
		}
		
		return weekDates;
	}
	
	/**
	 * 获取当年某周的最后一天
	 * 
	 * @param week
	 * @return
	 */
	public static Date getLastDayOfWeek(int week) {
		return getLastDayOfWeek(getCurrentYear(), week);
	}
	
	/**
	 * 得到当年周的总数 
	 * @return
	 */
	public static int getMaxWeekNumOfYear() {
		return getMaxWeekNumOfYear(getCurrentYear());
	}
	
	/** 
	 * 得到某一年周的总数 
	 */
	public static int getMaxWeekNumOfYear(int year) { 
		Calendar c = new GregorianCalendar(); 
		c.set(year, Calendar.DECEMBER, 31, 23, 59, 59);
		return getWeekOfYear(c.getTime()); 
	}
	
	/**
	 * 获取某年某周的最后一天
	 * 
	 * @param year
	 * @param week
	 * @return
	 */
	public static Date getLastDayOfWeek(int year, int week) {
		Calendar calendar = new GregorianCalendar();
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONDAY, Calendar.JANUARY);
		calendar.set(Calendar.DATE, 1);
		
		Calendar cal = (GregorianCalendar) calendar.clone();
		cal.add(Calendar.DATE, (week - 1) * 7);
		
		return getLastDayOfWeek(cal.getTime());
	}
	

	/** 取得当前日期是多少周 *
	 * @param date 
	 * @return 
	 * @throws Exception 
	 */  
	public static int getWeekOfYear(String date) throws Exception {
		return getWeekOfYear(toDate(date));
	}
	
	/** 取得当前日期是多少周 *
	 * @param date 
	 * @return 
	 */  
	public static int getWeekOfYear(Date date) { 
		Calendar c = new GregorianCalendar(); 
		c.setFirstDayOfWeek(Calendar.MONDAY); 
		c.setMinimalDaysInFirstWeek(7); 
		c.setTime(date);
		return c.get(Calendar.WEEK_OF_YEAR); 
	}
	
	public static Date toDate (String strDate) throws Exception
	{
		return toDate(strDate, "yyyy-MM-dd");
	}
	
	public static Date toDate (String strDate, String pattern) throws Exception
	{
		SimpleDateFormat sdf=new SimpleDateFormat(pattern);
		return sdf.parse(strDate); 
	}
	
	public static Date getMonthTime(java.util.Date date){
		Calendar cal = new GregorianCalendar();
		cal.setTime(date);
		cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
		cal.set(Calendar.HOUR_OF_DAY, cal.getActualMinimum(Calendar.HOUR_OF_DAY));
		cal.set(Calendar.MINUTE, cal.getActualMinimum(Calendar.MINUTE));
		cal.set(Calendar.SECOND, cal.getActualMinimum(Calendar.SECOND));
		cal.set(Calendar.MILLISECOND, cal.getActualMinimum(Calendar.MILLISECOND));
		return cal.getTime();
	}
	
	/**
	 * 
	 * @param date
	 * @return
	 */
	public static Integer getCurrentYear(){
		return getCurrentYear(new Date());
	}
	
	/**
	 * 
	 * @param date
	 * @return
	 */
	public static Integer getCurrentYear(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.YEAR);
	}
	
	/**
	 * 
	 * @param date
	 * @return
	 */
	public static Integer getCurrentMonth(){
		return Calendar.getInstance().get(Calendar.MONTH) + 1;
	}
	
	/**
	 * 
	 * @param date
	 * @return
	 */
	public static Integer getCurrentDay(){
		return Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
	}
	
	
	/**
     * get the date's month start time.
     * @param date
     * @return
     * @author <a href="mailto:rory.cn@gmail.com">somebody</a>
     */
	public static Date getMonthStartTime(Date date){
		Calendar cal = new GregorianCalendar();
		cal.setTime(date);
		cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
		cal.set(Calendar.HOUR_OF_DAY, cal.getActualMinimum(Calendar.HOUR_OF_DAY));
		cal.set(Calendar.MINUTE, cal.getActualMinimum(Calendar.MINUTE));
		cal.set(Calendar.SECOND, cal.getActualMinimum(Calendar.SECOND));
		cal.set(Calendar.MILLISECOND, cal.getActualMinimum(Calendar.MILLISECOND));
		return cal.getTime();
	}
	
	/**
	 * get the date's month end time.
	 * @param date
	 * @return
	 * @author <a href="mailto:rory.cn@gmail.com">somebody</a>
	 */
	public static Date getMonthEndTime(Date date){
		Calendar cal = new GregorianCalendar();
		cal.setTime(date);
		cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
		cal.set(Calendar.HOUR_OF_DAY, cal.getActualMaximum(Calendar.HOUR_OF_DAY));
		cal.set(Calendar.MINUTE, cal.getActualMaximum(Calendar.MINUTE));
		cal.set(Calendar.SECOND, cal.getActualMaximum(Calendar.SECOND));
		cal.set(Calendar.MILLISECOND, cal.getActualMaximum(Calendar.MILLISECOND));
		return cal.getTime();
	}
	
	public static void main(String[] args){
		System.out.println(UtilDate.getFirstDayOfWeek(new Date()));
		System.out.println(UtilDate.getLastDayOfWeek(new Date()));
		
		int weekNum = UtilDate.getWeekNumber();
		System.out.println(weekNum);
		
		System.out.println(UtilDate.getFirstDayOfWeek(0));
		System.out.println(UtilDate.getLastDayOfWeek(0));
		
		System.out.println(UtilDate.getMaxWeekNumOfYear());
	}
	
}
